/*
 * Copyright (C) 2004-2009  Autodesk, Inc.
* 
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2.1 of the GNU Lesser
* General Public License as published by the Free Software Foundation.
* 
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef CPP_UNIT_MAPINFOTESTS_H
#define CPP_UNIT_MAPINFOTESTS_H

#ifdef _WIN32
#pragma once
#endif // _WIN32

// Represents one FDO data property with a corresponding data value
class UnitTestData
{
public:
    wchar_t*    mPropertyName;
    wchar_t*    mPropertyDescription;
    FdoDataType mPropertyType;
    int         mPropertyLength;
    int         mPropertyPrecision;
    int         mPropertyScale;
    bool        mPropertyNullable;
    bool        mPropertyReadOnly;
    bool        mPropertyAutoGenerated;
    std::vector<const wchar_t*> mPropertyData;

    UnitTestData (
        wchar_t*    property_name,
        wchar_t*    property_description,
        FdoDataType property_type,
        int         property_length,
        int         property_precision,
        int         property_scale,
        bool        property_nullable,
        bool        property_readonly,
        bool        property_auto,
        ...) :
        mPropertyName (property_name),
        mPropertyDescription (property_description),
        mPropertyType (property_type),
        mPropertyLength (property_length),
        mPropertyPrecision (property_precision),
        mPropertyScale (property_scale),
        mPropertyNullable (property_nullable),
        mPropertyReadOnly (property_readonly),
        mPropertyAutoGenerated (property_auto)
    {
        const wchar_t* data;
        va_list varArgs;

        // Handle random list of property data:
        va_start (varArgs, property_auto);
        while (NULL != (data = va_arg (varArgs, const wchar_t*)))
            mPropertyData.push_back (data);
        va_end (varArgs);
    }
};

// Represents one FDO data property with a corresponding data value
class UnitTestClass
{
public:
    FdoStringP mName;
    FdoStringP mDescription;
    int mIdIndex;
    bool mSupportsLocking;
    bool mSupportsLT;
    std::vector<UnitTestData*> mProperties;

    UnitTestClass (
        wchar_t*    name,
        wchar_t*    description,
        int         id_index,
        bool        bSupportsLocking,
        bool        bSupportsLT,
        ...) :
        mName (name),
        mDescription (description),
        mIdIndex  (id_index),
        mSupportsLocking(bSupportsLocking),
        mSupportsLT(bSupportsLT)
    {
        UnitTestData* data;
        va_list varArgs;

        // Handle random list of properties:
        va_start (varArgs, bSupportsLT);
        while (NULL != (data = va_arg (varArgs, UnitTestData*)))
            mProperties.push_back (data);
        va_end (varArgs);
    }
};

class MapInfoTests :
    public CppUnit::TestCase
{
public:
    MapInfoTests (void);
    virtual ~MapInfoTests (void);

    static bool VERBOSE;
    static wchar_t* sLocation;
    static FdoIConnection* GetConnection ();

    // Parses the given Fdo string into an FdoExpression, making sure to validate and convert to the given type:
    static FdoExpression* ParseByDataType (const wchar_t* data, FdoDataType dataType);

    // Check that the given property in the given reader matches the given value:
    void checkEqual (FdoPtr<FdoIFeatureReader> reader, wchar_t* propertyName, FdoDataType propertyType, const wchar_t* propertyData);

    // check for the objects in the map (pairs of property index values & id numbers) by doing a select
    static void Expect (FdoIConnection* connection, UnitTestClass* definition, std::vector<int*> *map);

    // Accesses all the data on the current feature.
    void ProcessFeature (FdoIFeatureReader* featureReader, FdoIdentifierCollection* IDs = NULL);

    // Activate the given spatial context; don't report error if spatial context not found:
    void ActivateSpatialContext (FdoIConnection* connection, FdoString* scName);

    /// <summary>Copy a class.</summary>
    /// <param name="target_connection">A connection for the source class.</param> 
    /// <param name="target_class">The class name for the duplicate class.</param> 
    /// <param name="source_class">The class to duplicate.</param> 
    /// <param name="new_schema">If true, a new schema ("TheSchema") is created for the new class.</param> 
    void copy_schema (FdoIConnection* target_connection, FdoString* target_class, FdoFeatureClass* source_class, bool new_schema = true);

    /// <summary>Duplicate a class.</summary>
    /// <param name="target_connection">A connection for the source class.</param> 
    /// <param name="target_class">The class name for the duplicate class.</param> 
    /// <param name="file_name">Pass the file set name (full path but no extension).</param> 
    void copy (FdoIConnection* target_connection, FdoString* target_class, const wchar_t* file_name, bool ignore_states = false);

    void SaveSchema(FdoIConnection* connection);
};

#endif // CPP_UNIT_SHPTESTS_H

